
using System.Collections.Generic;
using System.Reflection;
using System;
using FairyGUI;
using SimpleJson;
using UnityEngine;

namespace ABA
{
    public class FGUIManager : Singleton<FGUIManager>
    {
        // 所有窗口的栈，包括dlg,view, 方便做窗口还原
        private Stack<FGUIWinInfo> winStack = new Stack<FGUIWinInfo>(); 
        Dictionary<string, FGUIWindow> windList = new Dictionary<string, FGUIWindow>();
        private float actTime = 0.35f;
        // private bool actState = false;
        public void InitUI()
        {
            // Event.inst.AddListener<FGUIWinInfo>(CommData.EVENT_SHOW_WINDOW, "FGUIManager2", _ShowWindow);
            // Event.inst.AddListener<FGUIWinInfo, JsonObject>(CommData.EVENT_SHOW_WINDOW, "FGUIManager3", _ShowWindow);
            // Event.inst.AddListener<FGUIWinInfo, int>(CommData.EVENT_SHOW_WINDOW, "FGUIManager31", _ShowWindow);
            // Event.inst.AddListener<FGUIWinInfo, string>(CommData.EVENT_SHOW_WINDOW, "FGUIManager32", _ShowWindow);
            // Event.inst.AddListener<FGUIWinInfo, Action>(CommData.EVENT_SHOW_WINDOW, "FGUIManager33", _ShowWindow);

            InitSysWin();
        }

        public FGUIWindow GetWindow(FGUIWinInfo info)
        {
            if (windList.ContainsKey(info.cls_name))
            {
                return windList[info.cls_name];
            }

            return null;
        }

        public FGUIWindow GetWindow(string cls_name)
        {
            if (windList.ContainsKey(cls_name))
            {
                return windList[cls_name];
            }
            return null;
        }

        public FGUIWindow ShowWindow(FGUIWinInfo info)
        {
            return __ShowWindow<bool>(info, false);
        }

        public FGUIWindow ShowWindow(FGUIWinInfo info, JsonObject param)
        {
            return __ShowWindow<JsonObject>(info, param);
        }
        public FGUIWindow ShowWindow(FGUIWinInfo info, JsonArray param)
        {
            return __ShowWindow<JsonArray>(info, param);
        }

        public FGUIWindow ShowWindow(FGUIWinInfo info, int param)
        {        
            return __ShowWindow<int>(info, param);
        }

        public FGUIWindow ShowWindow(FGUIWinInfo info, string param)
        {
            return __ShowWindow<string>(info, param);
        }

        public FGUIWindow ShowWindow(FGUIWinInfo info, Action param)
        {
            return __ShowWindow<Action>(info, param);
        }

        public void HideWindow(FGUIWinInfo info, bool force = false)
        {
            if (windList.ContainsKey(info.cls_name))
            {
                var wind = windList[info.cls_name];
                if (wind.isShowing)
                    wind.Hide();
            }
            else
            {
                if(!force){
                    Debug.LogWarning($"FGUIManager HideWindow {info.cls_name} is null");
                }
            }
        }

        // 隐藏当前所有逻辑对话框
        public void HideAllDialog()
        {
            foreach (var item in windList)
            {
                if (item.Value.winType == E_FGUIWIN_ZINDEX.DIALOG)
                {
                    if (item.Value.isShowing)
                        item.Value.Hide();
                }
            }
        }

        public void HideAllView()
        {
            foreach (var item in windList)
            {
                if (item.Value.winType == E_FGUIWIN_ZINDEX.VIEW || item.Value.winType == E_FGUIWIN_ZINDEX.TOP_VIEW || item.Value.winType == E_FGUIWIN_ZINDEX.BOTTOM_VIEW)
                {
                    if (item.Value.isShowing)
                        item.Value.Hide();
                }
            }
        }
        public bool CheckHasWinShowByPkgName(string pkgname){
            foreach (var item in windList)
            {
                if (item.Value.PkgName == pkgname && item.Value.isShowing)
                {
                    return true;
                }
            }

            return false;
        }

        public bool CheckHasShowingDlgBlockEventMask()
        {
            foreach (var item in windList)
            {
                if (item.Value.winType == E_FGUIWIN_ZINDEX.DIALOG && item.Value.isShowing && item.Value.IsHasBlockEventMask())
                {
                    return true;
                }
            }
            return false;
        }

        public void ActionOutView(FGUIWinInfo winInfo,string direction)
        {
           var win = GetWindow(winInfo);
           if(win != null){
                win.TweenMoveX(direction=="left"?-GRoot.inst.width:GRoot.inst.width ,actTime).SetEase(EaseType.SineOut).OnComplete(()=>{
                    win.Hide();
                });
           }
        }
        public void ActionInView(FGUIWinInfo winInfo,string direction)
        {
           var win = GetWindow(winInfo);
           if(win != null){
                if(direction != ""){
                    // UnityEngine.Debug.Log("ActionInView win.x = "+win.x);
                    if(direction=="left"){
                        if(win.x <= 0 ){
                            win.x = direction=="left"?GRoot.inst.width:-GRoot.inst.width;
                        }
                    }else if(direction=="right"){
                        if(win.x >= 0 ){
                            win.x = direction=="left"?GRoot.inst.width:-GRoot.inst.width;
                        }
                    }
                    GTween.Kill(win);
                    win.TweenMoveX(0 ,actTime).SetEase(EaseType.SineOut).OnComplete(()=>{
                        win.AniInOnComplete();
                    });
                }
                else{
                    win.x = 0;
                    win.AniInOnComplete();
                }
           }
        }
        // 删除窗口
        public void DisposeWindow(FGUIWinInfo info, bool forceDispose = false)
        {
            if (windList.ContainsKey(info.cls_name))
            {
                var wind = windList[info.cls_name];
                wind.Dispose();
                windList.Remove(info.cls_name);

                if(winStack.Contains(info)){
                    var yy = new Stack<FGUIWinInfo>();
                    var xx = winStack.ToArray();
                    for (int i = 0; i < xx.Length; i++)
                    {
                        if(xx[i] != info){
                            yy.Push(xx[i]);
                        }
                    }   
                    winStack = yy;             
                }
            }
            else
            {
                if(forceDispose == false)
                    Debug.LogWarning($"FGUIManager DisposeWindow {info.cls_name} is null");
            }
        }

        // 删除所有UI窗口，包括view 与 dlg
        public void DisposeAllWindow()
        {
            foreach (var item in windList)
            {
                var wind = item.Value;
                wind.Dispose();
            }

            windList.Clear();
            winStack.Clear();
        }

        public bool IsWinShowFromName(string clsName)
        {
            return windList[clsName].isShowing;
        }

        private void InitSysWin()
        {
            SysTips.inst.Active();
            SysDlg.inst.Active();
            SysLoading.inst.Active();
            SysLoadingNet.inst.Active();
        }

        private void PushToStack(FGUIWinInfo info)
        {
            winStack.Push(info);
            if(winStack.Count > 150){
                var yy = new Stack<FGUIWinInfo>();
                var xx = winStack.ToArray();
                for (int i = xx.Length - 100; i < xx.Length; i++)
                {
                    yy.Push(xx[i]);
                }
                winStack = yy;
            }
        }

        public Stack<FGUIWinInfo> GetWinStack()
        {
            return winStack;
        }

        private FGUIWindow __ShowWindow<T>(FGUIWinInfo info, T param)
        {
            string clsName = "ABA." + info.cls_name;
            Type type = Type.GetType(clsName);

            FGUIWindow wind;
            if (windList.ContainsKey(info.cls_name))
            {
                wind = windList[info.cls_name];
                if (!wind.isShowing)
                {
                    wind.Show();
                    InitAfterShow(type, wind, param);

                    PushToStack(info);
                }
            }
            // 创建
            else
            {
                if (typeof(T) == typeof(bool))
                {
                    wind = Activator.CreateInstance(type, info) as FGUIWindow;
                }
                else
                {
                    wind = Activator.CreateInstance(type, info, param) as FGUIWindow;
                }

                windList.Add(info.cls_name, wind);
                if (wind.autoFirstShow)
                {               
                    wind.Show();
                    InitAfterShow(type, wind, param);

                    PushToStack(info);
                }
            }
            
            return wind;
        }

        private void InitAfterShow<T>(Type type, object obj, T param)
        {
            MethodInfo method = null;
            object[] paras = null;
            if (typeof(T) == typeof(bool))
            {
                //加载无参方法
                method = type.GetMethod("InitAfterShow");
            }
            else
            {
                paras = new object[] { param };
                //加载有参方法
                method = type.GetMethod("InitAfterShow", new Type[] { typeof(T) });
            }

            //类型转换并返回
            method.Invoke(obj, paras);
        }

        // private void _ShowWindow(FGUIWinInfo info)
        // {
        //     __ShowWindow<bool>(info, false);
        // }

        // private void _ShowWindow(FGUIWinInfo info, JsonObject param)
        // {
        //     __ShowWindow<JsonObject>(info, param);
        // }
        // private void _ShowWindow(FGUIWinInfo info, JsonArray param)
        // {
        //     __ShowWindow<JsonArray>(info, param);
        // }
        // private void _ShowWindow(FGUIWinInfo info, int param)
        // {
        //     __ShowWindow<int>(info, param);
        // }
        // private void _ShowWindow(FGUIWinInfo info, string param)
        // {
        //     __ShowWindow<string>(info, param);
        // }
        // private void _ShowWindow(FGUIWinInfo info, Action param)
        // {
        //     __ShowWindow<Action>(info, param);
        // }
    }
}
